/**
 * JC - Java Calls.
 * Transforms requests into calls to the Java backend.
 */
package gmat.impl

import gmat.intr.Matrix
/**
 * @author Aram Altschudjian
 *
 */
public class MatrixJC implements Matrix{
	jmat.intr.Matrix matrix
	
	MatrixJC(){
		matrix = new jmat.impl.MatrixJC()
	}
	
	MatrixJC(jmat.intr.Matrix matrix){
		this.matrix = matrix
	}
	
	MatrixJC(List sizes){
		matrix = new jmat.impl.MatrixJC(sizes)
	}
	
	MatrixJC(int... sizes){
		matrix = new jmat.impl.MatrixJC((java.lang.Integer[])sizes)
	}
	
	MatrixJC(Object data){
		matrix = new jmat.impl.MatrixJC(data)
	}
	
	MatrixJC(Object data, List sizes){
		matrix = new jmat.impl.MatrixJC(data, sizes)
	}
	
	static make(List data){
		MatrixJC matrix = new MatrixJC()
		matrix.leftShift(data)
		return matrix
	}
	
	static zeros(List sizes){
		MatrixJC matrix = new MatrixJC(sizes)
		matrix.init(0)
		return matrix
	}
	
	static ones(List sizes){
		MatrixJC matrix = new MatrixJC(sizes)
		matrix.init(1)
		return matrix
	}
	
	static zeros(int... sizes){
		MatrixJC matrix = new MatrixJC(sizes)
		matrix.init(0)
		return matrix
	}
	
	static ones(int... sizes){
		MatrixJC matrix = new MatrixJC(sizes)
		matrix.init(1)
		return matrix
	}
	
	def init(Object defaultValue){
		matrix.init(defaultValue)
	}
	
	def init(Object defaultValue, List sizes){
		matrix.init(defaultValue, sizes)
	}
	
	def init(Object defaultValue, int... sizes){
		matrix.init(defaultValue, sizes)
	}
	
	def data(Object data){
		matrix.data(data)
	}
	
	def data(){
		return matrix.data()
	}
	
	def val(){
		return matrix.val()
	}
	
	def entries(){
		return matrix.entries()
	}
	
	def indices(){
		return matrix.indices()
	}
	
	def leftShift(List data){
		matrix.assign(data)
	}
	
	def leftShift(jmat.intr.Matrix data){
		matrix.assign(data)
	}
	
	def leftShift(gmat.intr.Matrix data){
		matrix.assign(data.matrix)
	}
	
	def getAt(String address){
		return new MatrixJC(matrix.get(address))
	}
	
	def getAt(Object address){
		// The following is a nasty workaround, needed  because whenever Groovy sees
		// brackets [], it thinks "oh wow, the programmer MUST mean a list!"
		def result
		if(address instanceof List){
			result = matrix.get(address.toArray())
		} else{
			result = matrix.get(address)
		}
		return new MatrixJC(result)
	}
	
	def getAt(Object... address){
		return new MatrixJC(matrix.get(address))
	}
	
	def rightShift(List address){
		return new MatrixJC(matrix.get(address))
	}
	
	def putAt(String address, Object entry){
		matrix.put(address, entry)
	}
	
	def putAt(Object address, Object entry){
		matrix.put(address, entry)
	}
	
	def find(Object entry){
		return matrix.find(entry)
	}
	
	def nfind(Object entry){
		return matrix.nfind(entry)
	}
	
	def count(Object entry){
		return matrix.count(entry)
	}
	
	def setDim(int dimensions){
		matrix.setDim(dimensions)
	}
	
	def getDim(){
		return matrix.getDim()
	}
	
	def setSize(List sizes){
		matrix.setSize(sizes)
	}
	
	def setSize(int... sizes){
		matrix.setSize(sizes)
	}
	
	def size(){
		return matrix.size()
	}
	
	def size(int dimension){
		return matrix.size(dimension)
	}
	
	def list(){
		return matrix.list()
	}
	
	def unique(){
		return matrix.unique()
	}
	
	def isEmpty(){
		return matrix.isEmpty()
	}
	
	def equals(Matrix candidate){
		return matrix.equals(candidate.matrix)
	}
	
	def rows(){
		return matrix.size(0)
	}
	
	def cols(){
		return matrix.size(1)
	}
	
	def pages(){
		return matrix.size(2)
	}
	
	def max(){
		// Unsupported
		return matrix.max()
	}
	
	def maxIndex(){
		// Unsupported
		return matrix.maxIndex()
	}
	
	def min(){
		// Unsupported
		return matrix.min()
	}
	
	def minIndex(){
		// Unsupported
		return matrix.minIndex()
	}
	
	def sum(){
		// Unsupported
		return matrix.sum()
	}
	
	def sumAll(){
		// Unsupported
		return matrix.sumAll()
	}
	
	def plus(Matrix matrix){
		return new MatrixJC(this.matrix.plus(matrix.matrix))
	}
	
	def plus(Number number){
		return new MatrixJC(matrix.plus(number))
	}
	
	def minus(Matrix matrix){
		return new MatrixJC(this.matrix.minus(matrix.matrix))
	}
	
	def minus(Number number){
		return new MatrixJC(matrix.minus(number))
	}
	
	def multiply(Matrix matrix){
		return new MatrixJC(this.matrix.mult(matrix.matrix))
	}
	
	def multiply(Number number){
		return new MatrixJC(matrix.mult(number))
	}
	
	def div(Matrix matrix){
		return new MatrixJC(this.matrix.div(matrix.matrix))
	}
	
	def div(Number number){
		return new MatrixJC(matrix.div(number))
	}
	
	def log(){
		return new MatrixJC(matrix.log())
	}
	
	def subFrom(Number minuend){
		return new MatrixJC(matrix.subFrom(minuend))
	}
	
	def extend(int dimension, int amount = 1){
		matrix.extend(dimension, amount)
	}
	
	def delete(int dimension, Object address){
		matrix.delete(dimension, address)
	}
	
	def delete(int dimension, Object... address){
		matrix.delete(dimension, address)
	}
	
	def delete(List address){
		matrix.delete(address)
	}
	
	def delete(Object... address){
		matrix.delete(address)
	}
	
	def setOrder(int dimension, List order){
		matrix.setOrder(dimension, order)
	}
	
	def setOrder(int dimension, int... order){
		matrix.setOrder(dimension, order)
	}
	
	def addDim(int size, int index){
		matrix.addDim(size, index)
	}
	
	def setName(int dimension, int index, String name){
		matrix.setName(dimension, index, name)
	}
	
	def setNames(int dimension, Map nameToIndexMap){
		matrix.setName(dimension, nameToIndexMap)
	}
	
	def getNames(int dimension){
		return matrix.getNames(dimension)
	}
	
	def resolve(int dimension, String name){
		return matrix.resolve(dimension, name)
	}
	
	def convert(int address){
		return matrix.convert(address)
	}
	
	def convert(List address){
		return matrix.convert(address)
	}
	
	def convert(Object... address){
		return matrix.convert(address)
	}
	
	String toString(){
		return matrix.toString()
	}
}
